#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hs/hs.h>

#define BUF_SIZE 5

// 定义一个回调函数，当匹配时被调用
static int on_match(unsigned int id, unsigned long long from,
        unsigned long long to, unsigned int flags, void *ctx);

int main()
{
    char *pat = "hello";

    // 编译正则表达式
    hs_database_t *database;
    hs_compile_error_t *compile_err;
    // 指定流模式
    hs_error_t err = hs_compile(pat, HS_FLAG_DOTALL, HS_MODE_STREAM,
                                NULL, &database, &compile_err);
    if (err != HS_SUCCESS) {
        fprintf(stderr, "ERROR: Unable to compile pattern \"%s\": %s\n",
                pat, compile_err->message);
        hs_free_compile_error(compile_err);
        return 1;
    }

    // 分配临时空间(指针必须初始化为NULL)
    hs_scratch_t *scratch = NULL;
    if(hs_alloc_scratch(database, &scratch) != HS_SUCCESS)
    {
        fprintf(stderr, "ERROR: Unable to allocate scratch space.
                Exiting.\n");
        hs_free_database(database);
        exit(EXIT_FAILURE);
    }

    // 创建流匹配指针
    hs_stream_t *stream = NULL;
    err = hs_open_stream(database, 0, &stream);
    if (err != HS_SUCCESS) {
        fprintf(stderr, "Error creating stream: %d\n", err);
        hs_free_database(database);
        return -1;
    }

    // 读入数据
    char buf[BUF_SIZE];
    size_t len;
    FILE *fp = fopen("input.txt", "r");
    if (fp == NULL) {
        perror("Error opening input file");
        hs_close_stream(stream, scratch, NULL, NULL);
        hs_free_database(database);
        hs_free_scratch(scratch);
        return -1;
    }

    // 单模+文件流匹配
    while ((len = fread(buf, 1, BUF_SIZE, fp)) > 0) {
        printf("File stream: \n%s\n", buf);
        err = hs_scan_stream(stream, buf, len, 0, scratch, on_match, pat);
        if (err != HS_SUCCESS) {
            fprintf(stderr, "Error scanning stream: %d\n", err);
            break;
        }
    }
    if (ferror(fp)) {
        perror("Error reading input file");
    }

    // 关闭流
    hs_close_stream(stream, scratch, NULL, NULL);
    // 释放空间
    hs_free_scratch(scratch);
    hs_free_database(database);
    // 关闭文件
    fclose(fp);

    return 0;
}

// 定义一个回调函数，当匹配时被调用
static int on_match(unsigned int id, unsigned long long from,
        unsigned long long to, unsigned int flags, void *ctx)
{
    char *tmp = (char*)ctx;

    printf("The pattern is %s\n", tmp);
    printf("Match found at end offset %llu\n", to);

    return 0;
}
